package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect// 表示当前类是一个切面类
@Component// 切面对象本质也是一个spring中的一个bean对象
@Slf4j
public class AutoFillAspect {
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {
    }


    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) {
        log.info("前置通知开始执行");
        //为实体类中公共的属性赋值
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获得当前被拦截的方法对象
        Method method = signature.getMethod();

        //获得当前方法上的注解对象
        AutoFill annotation = method.getAnnotation(AutoFill.class);

        //获得当前数据库操作类型 从注解中就可以获取到
        //本次数据库操作的类型
        OperationType operationType = annotation.type();
        System.out.println(operationType);

        //实体类在哪？
        Object[] args = joinPoint.getArgs();
        Object entity=null;
        if (args != null && args.length > 0){
            entity=args[0];
        }
        //赋的值时什么？
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();

        //判断当前数据库操作类型
        if (operationType == OperationType.INSERT){
            try {
                //获得实体类中的公共属性
                Method setCreateTimeMethod = entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
                setCreateTimeMethod.invoke(entity,now);
                Method setUpdateTimeMethod = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                setUpdateTimeMethod.invoke(entity,now);
                Method setCreateUserMethod = entity.getClass().getDeclaredMethod("setCreateUser", Long.class);
                setCreateUserMethod.invoke(entity,currentId);
                Method setUpdateUserMethod = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
                setUpdateUserMethod.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            try {
                //获得实体类中的公共属性
                Method setUpdateTimeMethod = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                setUpdateTimeMethod.invoke(entity,now);
                Method setUpdateUserMethod = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
                setUpdateUserMethod.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
